package com.xiao.service.impl;

import com.xiao.domain.ResponseResult;
import com.xiao.domain.constants.RedisConstants;
import com.xiao.domain.pojo.BlogSysUser;
import com.xiao.domain.pojo.LoginUser;
import com.xiao.service.AdminLoginService;
import com.xiao.utils.JwtUtil;
import com.xiao.utils.RedisCache;
import com.xiao.utils.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Objects;

@Service
public class AdminLoginServiceImpl implements AdminLoginService {
    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisCache redisCache;

    @Override
    public ResponseResult login(BlogSysUser blogSysUser) { // BlogSysUser 是实体类 下面 的 LoginUser 是 登入时用的 实体类 不一样


        // 1. 使用 token 封装 登录信息
        UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(blogSysUser.getUserName(), blogSysUser.getPassword());

        // 2. 利用 token 生成 Authentication 对象
        Authentication authenticate = authenticationManager.authenticate(token);
        // 3. 如果 authenticate 对象为 null 则 抛出异常
        if (Objects.isNull(authenticate)){// authenticate==null
            throw new RuntimeException("运行时异常: 用户名错误或密码错误"); // 抛出异常后，下面就不会执行
        }
        // 4. 利用 authenticate 创建 登入对象
        LoginUser loginUser = (LoginUser) authenticate.getPrincipal();
        // 5. 利用登入对象，提取登入信息
        Long userId = loginUser.getBlogSysUser().getId();
        String jwt = JwtUtil.createJWT(String.valueOf(userId));
        // 6. 把登入信息存入 Redis
        redisCache.setCacheObject(RedisConstants.ADMIN_LOGIN_PREFIX+userId,loginUser);// 这里 使用后台登录的键前缀  ADMIN_LOGIN_PREFIX = "admin-login:"
        // 7. 把 token  封装后 返回
        HashMap<String, String> hashMap = new HashMap<>();
        hashMap.put("token",jwt);
        // 8. 封装成 ResponseResult 后 返回
        ResponseResult responseResult = ResponseResult.okResult(hashMap);
        return responseResult;
    }

    @Override
    public ResponseResult logout() {
        // 获取当前用户登录的用户ID
        Long userId = SecurityUtils.getUserId();
        // 删除 redis 中对应的数据
        redisCache.deleteObject(RedisConstants.ADMIN_LOGIN_PREFIX+userId);
        return ResponseResult.okResult();
    }
}
